package com.sunb2b.web.controller;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;

import com.sunb2b.entity.Category;
import com.sunb2b.entity.CategoryAttr;
import com.sunb2b.entity.CompanyMember;
import com.sunb2b.entity.Member;
import com.sunb2b.entity.Product;
import com.sunb2b.entity.ProductDetail;
import com.sunb2b.pojo.PageSearchResult;
import com.sunb2b.service.CategoryService;
import com.sunb2b.service.MemberService;
import com.sunb2b.service.ProductService;
import com.sunb2b.service.Staticizer;
import com.sunb2b.util.WebUtils;
import com.sunb2b.web.form.SearchCriteria;

import freemarker.template.TemplateException;

@Controller
public class ProductController {
    
    @Inject
    private MemberService memberService;
    
    @Inject
    private CategoryService categoryService;
    
    @Inject
    private ProductService productService;
    
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm");
    
    @ModelAttribute("product")
    public Product createProduct() {
        return new Product();
    }
    
    @RequestMapping(value="/product/update", method=RequestMethod.GET)
    public String preUpdateProd(@ModelAttribute("product") Product product, 
    		HttpServletRequest request, 
    		Model model){
        String categoryId = request.getParameter("categoryId");
        String _id = request.getParameter("id");
        model.addAttribute("isAdmin", WebUtils.isAdmin(request));
        if(_id!=null){
            // update product, fetch product info and goto product update page
            int id = Integer.parseInt(_id);
            Product prod = productService.getProduct(id);
            prod.setProductDetails(productService.getProductDetailsByProduct(prod));
            model.addAttribute("product", prod);
            if(WebUtils.isAdmin(request)){
            	List<CompanyMember> allMembers = memberService.listAllCompanyMember();
            	model.addAttribute("allMembers", allMembers);
            }
            return null;
        }
        else if(categoryId!=null){
            // goto product add page
            product.setCategoryId(categoryId);
            Category c = categoryService.getCategory(categoryId);
            product.setCategory(c);
            Set attrs = c.getCategoryAttrs();
            Iterator itr = attrs.iterator();
            while(itr.hasNext()){
                CategoryAttr categoryAttr = (CategoryAttr)itr.next();
                ProductDetail pd = new ProductDetail();
                pd.setCategoryAttr(categoryAttr);
                product.getProductDetails().add(pd);
            }
            if(WebUtils.isAdmin(request)){
            	List<CompanyMember> allMembers = memberService.listAllCompanyMember();
            	model.addAttribute("allMembers", allMembers);
            }
            return null;
        }
        else{
            // goto category select page
            return "product/selectCategory";
        }
        
    }

    @RequestMapping(value="/product/update", method=RequestMethod.POST)
    public String update(@Valid Product product, 
    		BindingResult result, 
    		HttpServletRequest request, 
    		HttpSession session,
    		Model model) throws IOException, TemplateException{
        if( (("".equals(product.getBigImage()))||product.getBigImage()==null) &&
        		(product.getBigImageFile()==null||product.getBigImageFile().getSize()==0)){
        	result.rejectValue("bigImageFile", "", "该项不能为空");
        }
        
        if(product.getBigImageFile()!=null&&product.getBigImageFile().getSize()!=0){ 
    		if(!WebUtils.isPicture(product.getBigImageFile())){
    			result.rejectValue("bigImageFile", "", "不是有效的图片");
    		}
    		else if(product.getBigImageFile().getSize()>2000000){
    			result.rejectValue("iconImageFile", "", "图片不能超过2M");
    		}
        }
        
        if( (("".equals(product.getIconImage()))||product.getIconImage()==null) &&
        		(product.getIconImageFile()==null||product.getIconImageFile().getSize()==0)){
        	result.rejectValue("iconImageFile", "", "该项不能为空");
        }
        
        if(product.getIconImageFile()!=null&& product.getIconImageFile().getSize()!=0){ 
    		if(!WebUtils.isPicture(product.getIconImageFile())){
    			result.rejectValue("iconImageFile", "", "不是有效的图片");
    		}
    		else if(product.getIconImageFile().getSize()>2000000){
    			result.rejectValue("iconImageFile", "", "图片不能超过2M");
    		}
        }
        
        if(!WebUtils.checkValidCode(request)){
        	result.rejectValue("validCode", "", "验证码错误");
        }
        
        if(result.hasErrors()) {
            return null;
        }
        
        for(int i=0; i<product.getProductDetails().size(); i++){
            ProductDetail pd = (ProductDetail)product.getProductDetails().get(i);
            pd.setProduct(product);
        }
        
        Member member = null;
        if(product.getMemberId()!=null&&product.getMemberId()!=0){
        	member = memberService.getMember(product.getMemberId());
        }
        else{
        	member = (Member)session.getAttribute("member");
        }
        product.setMember(member);
        
        product.setDateCreated(new Date());
        
        String currentPath = request.getSession().getServletContext().getRealPath("/");
        //System.out.println("current servlet real path: " + currentPath);
        File uploadImageDir = new File(currentPath + "upload/images/" + member.getId() + "/");
        if(!uploadImageDir.exists()){
            uploadImageDir.mkdir();
        }
        
        MultipartFile iconFile = product.getIconImageFile();
        if(iconFile!=null&&iconFile.getSize()!=0){
            String iconImageName = member.getId() + "/" + new Date().getTime() 
            		+ WebUtils.getExtName(iconFile);
            product.setIconImage(iconImageName);
            File iconImageFile = new File(currentPath + "upload/images/" + iconImageName);
            iconImageFile.createNewFile();
            iconFile.transferTo(iconImageFile);
        }
        
        MultipartFile bigFile = product.getBigImageFile();
        if(bigFile!=null&&bigFile.getSize()!=0){
            String bigImageName = + member.getId() + "/" + new Date().getTime() 
            		+ WebUtils.getExtName(bigFile);
            product.setBigImage(bigImageName);
            File bigImageFile = new File(currentPath + "upload/images/" + bigImageName);
            bigImageFile.createNewFile();
            bigFile.transferTo(bigImageFile);
        }
        product.setDateCreated(new Date());
        productService.save(product);
        product.setsDateCreated(sdf.format(product.getDateCreated()));
        Staticizer staticizer = new Staticizer(currentPath + "/tpl");
        staticize(staticizer, product, member, currentPath);
        String message = "表单提交成功";
        model.addAttribute("message", message);
        
        return null;
        
    }
    
    @RequestMapping(value="/product/list", method=RequestMethod.GET)
    public String list(@Valid SearchCriteria crit, 
    		HttpSession session, 
    		Model model) throws IOException{
    	DetachedCriteria dc = DetachedCriteria.forClass(Product.class);
    	if(crit.getCategoryId()!=null){
    		dc.add(Restrictions.like("categoryId", crit.getCategoryId(), MatchMode.START));
    	}
    	if(crit.getRegionId()!=null){
    		dc.add(Restrictions.like("regionId", crit.getRegionId(), MatchMode.START));
    	}
    	if(crit.getMemberId()!=null&&crit.getMemberId()!=0){
    		dc.add(Restrictions.eq("memberId", crit.getMemberId()));
    	}
    	else{
    		Member member = (Member)session.getAttribute("member");
    		dc.add(Restrictions.eq("member", member));
    	}
    	PageSearchResult rs = productService.search(dc, crit.getPage(), crit.getPageSize());
    	model.addAttribute("results", rs);
    	System.out.println(rs);
        return null;
    }

    @RequestMapping(value="/admin/product/preStaticize", method=RequestMethod.GET)
    public String preCreateIndex(Model model) throws IOException{
        return "/admin/product/staticize";
    }
   
    @RequestMapping(value="/admin/product/staticize", method=RequestMethod.GET)
    public String updateIndex(HttpServletRequest request, Model model) 
    			throws IOException, TemplateException{
        File f = new File(".");
    	//System.out.println(f.getAbsolutePath());
        List<Product> products = productService.listAll();
        String currentPath = request.getSession().getServletContext().getRealPath("/");
        Staticizer staticizer = new Staticizer(currentPath + "/tpl");
        for(Product p : products){
        	p.setsDateCreated(sdf.format(p.getDateCreated()));
            p.setProductDetails(productService.getProductDetailsByProduct(p));
            if(p.getMember()==null||p.getMember().getName()==null){
            	System.out.println("!!!!!!!!!!!!!!!!!!!!!" + p.getId());
            	
            }
            staticize(staticizer, p, p.getMember(), currentPath);
        }
        String message = "Operation was done successfully.";
        model.addAttribute("message", message);
        return null;
    }
    
    private void staticize(Staticizer staticizer, Product p, Member m, String currentPath) 
    		throws IOException, TemplateException{
        Map data = new HashMap();
        data.put("product", p);
        data.put("member", m);
        Map env = new HashMap();
        env.put("data", data);
        env.put("tpl", "product.ftl");
        env.put("outputFileName", currentPath + "/products/" 
        		+ p.getCategoryId() + "/" + p.getId() + ".html");
        staticizer.process(env);
    }
    
    @RequestMapping(value="/product/delete")
    public String delete(int id, HttpSession session, HttpServletResponse response) throws Exception{
    	if(id!=0){
    		Member m = (Member)session.getAttribute("member");
    		Product p = productService.getProduct(id);
    		if(!p.getMember().getId().equals(m.getId())){
    			throw new Exception("Unahthorized operation");
    		}
    		p.setStatus("delete");
    		productService.save(p);
    	}
    	return "redirect:/product/list?page=1&pageSize=10";
    }
   
}
